package com.xian.im.modules.sensitive.service;

import com.google.common.base.Preconditions;
import com.xian.im.modules.sensitive.suporrt.RedisBloomFilterHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @program: xian-im-server
 * @description:
 * @author: liru.xian
 * @create: 2021-02-23 10:17
 **/
@Slf4j
@Component
public class RedisService {

    private final RedisTemplate<String,Object> redisTemplate;
    private AtomicInteger integer = new AtomicInteger();

    public RedisService(RedisTemplate<String,Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 根据给定的布隆过滤器添加值
     */
    public <T> void addByBloomFilter(RedisBloomFilterHelper<T> bloomFilterHelper, String key, T value) {
        StopWatch stopWatch = new StopWatch("addByBloomFilter");
        stopWatch.start("checkArgument ");
        Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空");
        stopWatch.stop();
        stopWatch.start("murmurHashOffset");
        int[] offset = bloomFilterHelper.murmurHashOffset(value);
        stopWatch.stop();
        log.info(" value {} offset.length {}" ,value,offset.length);
        stopWatch.start("setBit");
        for (int i : offset) {
            redisTemplate.opsForValue().setBit(key, i, true);
        }
        stopWatch.stop();
        log.info("执行结果 {}",stopWatch.prettyPrint());
    }

    /**
     * 根据给定的布隆过滤器添加值
     */
    public <T> void addByBloomFilter(RedisBloomFilterHelper<T> bloomFilterHelper, String key, Collection<T> value) {
        Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空");
        StopWatch stopWatch = new StopWatch("addByBloomFilter");
        stopWatch.start("murmurHashOffset");
        for (T t : value) {
            integer.getAndIncrement();
            if(integer.get() % 50 == 0){
                System.out.println(integer.get());
            }
            int[] offset = bloomFilterHelper.murmurHashOffset(t);
            for (int i : offset) {
                redisTemplate.opsForValue().setBit(key, i, true);
            }
        }
        stopWatch.stop();
    }

    /**
     * 根据给定的布隆过滤器判断值是否存在
     */
    public <T> boolean includeByBloomFilter(RedisBloomFilterHelper<T> bloomFilterHelper, String key, T value) {
        Preconditions.checkArgument(bloomFilterHelper != null, "bloomFilterHelper不能为空");
        int[] offset = bloomFilterHelper.murmurHashOffset(value);
        for (int i : offset) {
            if (!redisTemplate.opsForValue().getBit(key, i)) {
                return false;
            }
        }
        return true;
    }

    /**
     *
     * @param sky
     * @return
     */
    public Boolean exist(String sky){
        return  redisTemplate.hasKey(sky);
    }

}
